package com.shermanzhou.learn.learnjava8.streamapi;

import com.shermanzhou.learn.learnjava8.streamapi.model.Employee;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhouchaoqun
 * @email zhouchaoqun@quancheng-ec.com
 * @created 2017/10/2 下午3:35
 */
public class TestStreamAPI {
    private long start;
    private long end;

    List<Employee> employees = Arrays.asList(
            new Employee("aa", 11, 1111, Employee.Status.FREE),
            new Employee("bb", 11, 2222, Employee.Status.BUSY),
            new Employee("cc", 33, 3333, Employee.Status.FREE),
            new Employee("dd", 33, 4444, Employee.Status.VOCATION),
            new Employee("ee", 44, 3333, Employee.Status.FREE)
    );

    @Before
    public void before() {
        start = System.currentTimeMillis();
    }

    @After
    public void after() {
        end = System.currentTimeMillis();
        System.out.println("cost: " + (end - start) + " ms");
    }

    /**
     * 查找与匹配
     * allMatch -- 检查是否匹配所有元素
     * anyMatch -- 检查是否至少一个匹配
     * noneMatch -- 检查是否所有元素都不匹配
     * findFirst -- 返回第一个元素
     * findAny -- 返回任意一个元素
     * count
     * max
     * min
     */
    @Test
    public void test1() {
        boolean b1 = employees.stream()
                .allMatch((x) -> x.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b1);

        boolean b2 = employees.stream()
                .anyMatch((x) -> x.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b2);

        boolean b3 = employees.stream()
                .noneMatch((x) -> x.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b3);

        Optional<Employee> firstEmp = employees.stream()
                .sorted((e1, e2) -> -Integer.compare(e1.getAge(), e2.getAge()))
                .findFirst();
        System.out.println(firstEmp.get());

        Optional<Employee> any = employees.parallelStream()
                .filter((x) -> x.getStatus().equals(Employee.Status.FREE))
                .findAny();
        System.out.println(any.get());

        long count = employees.stream()
                .count();
        System.out.println(count);

        Optional<Employee> max = employees.stream()
                .max(Comparator.comparingDouble(Employee::getSalary));
        System.out.println(max.get());

        Optional<Employee> min = employees.stream()
                .min(Comparator.comparingInt(Employee::getAge));
        System.out.println(min.get());
    }

    /**
     * 归约： reduce
     * <p>
     * Optional<T> reduce(BinaryOperator<T> accumulator);
     * T reduce(T identity, BinaryOperator<T> accumulator);
     */
    @Test
    public void test2() {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum = integers.stream()
                .reduce(0, (x, y) -> x + y);
        System.out.println(sum);

        System.out.println("---------------------------");

        Double sum2 = employees.stream()
                .map(Employee::getSalary)
                .reduce(0D, (x, y) -> x + y);
        System.out.println(sum2);

        System.out.println("---------------------------");

        Optional<Double> sum3 = employees.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);
        System.out.println(sum3.get());
    }

    /**
     * 收集
     * collect
     */
    @Test
    public void test3() {
        List<String> names = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());
        System.out.println(names);

        Map<Employee.Status, List<Employee>> statusListMap = employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(statusListMap);

        Map<Employee.Status, Long> collect = employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.counting()));
        System.out.println(collect);

        TreeMap<Employee.Status, Long> collect1 = employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, TreeMap::new, Collectors.counting()));
        System.out.println(collect1);


    }

}
